import { throttle as _throttle } from 'lodash'

// 判断class有无
function hasClass(ele, cls) {
  if (ele) {
    cls = cls || ''
    if (cls.replace(/\s/g, '').length === 0) return false // 当cls没有参数时，返回false
    return new RegExp(' ' + cls + ' ').test(' ' + ele.className + ' ')
  }
}

export default {
  bind(el, binding, vnode) {
    if (binding.arg && !binding.arg) return

    const dialogHeaderEl = el.querySelector('.dialog-header')
    let dragDom = el
    // 检测是否modal对话框
    if (!hasClass(el, 'no-modal')) {
      dragDom = el.querySelector('.dialog-content')
    }
    // 修改drag的鼠标样式
    dialogHeaderEl.style.cssText += ';cursor:move;'

    // dragDom样式中left、top的值必须为一个数字,而不是auto
    // dragDom.style.cssText += ';left:0px;top:0px;'

    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const getStyle = (function() {
      if (window.document.currentStyle) {
        return (dom, attr) => dom.currentStyle[attr]
      } else {
        return (dom, attr) => getComputedStyle(dom, false)[attr]
      }
    })()

    // drag元素鼠标按下事件处理
    const handleDown = e => {
      // 鼠标按下，计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft
      const disY = e.clientY - dialogHeaderEl.offsetTop

      const dragDomWidth = dragDom.offsetWidth
      const dragDomHeight = dragDom.offsetHeight

      const screenWidth = document.body.clientWidth
      const screenHeight = document.body.clientHeight

      const minDragDomLeft = dragDom.offsetLeft
      const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth

      const minDragDomTop = dragDom.offsetTop
      const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight

      // 获取到的值带px 正则匹配替换
      let styL = getStyle(dragDom, 'left')
      let styT = getStyle(dragDom, 'top')

      if (styL.includes('%')) {
        styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)
        styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)
      } else {
        styL = +styL.replace(/\px/g, '')
        styT = +styT.replace(/\px/g, '')
      }

      // 文档对象的鼠标移动事件处理
      // TODO 经过测试,发现timeout设置100以下比较流畅,大于100就有明显的卡顿!!!
      const handleMove = _throttle(e => {
        // 通过事件委托，计算移动的距离
        let left = e.clientX - disX
        let top = e.clientY - disY

        // 边界处理
        if (-left > minDragDomLeft) {
          left = -minDragDomLeft
        } else if (left > maxDragDomLeft) {
          left = maxDragDomLeft
        }

        if (-top > minDragDomTop) {
          top = -minDragDomTop
        } else if (top > maxDragDomTop) {
          top = maxDragDomTop
        }

        // 移动当前元素
        dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`

        // emit drag event
        // vnode.context.$emit('drag')
        // 触发组件的回调,由组件再进一步处理
        if (binding.value && binding.value.handler) {
          binding.value.handler({
            left: left + styL,
            top: top + styT
          })
        }
      }, 90)

      // 文档对象的鼠标松开事件
      const handleUp = e => {
        document.documentElement.removeEventListener(
          'mousemove',
          handleMove,
          false
        )
        document.documentElement.removeEventListener('mouseup', handleUp, false)
      }
      // if (e.preventDefault) {
      //   e.preventDefault()
      // } else {
      //   e.returnValue = false
      // }
      // 注册事件
      document.documentElement.addEventListener('mousemove', handleMove, false)
      document.documentElement.addEventListener('mouseup', handleUp, false)
    }
    // 注册事件
    dialogHeaderEl.addEventListener('mousedown', handleDown, false)
  }
}
